;; Copyright 2010 Peter Goncharov

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or	
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(in-package :cl-money-type)

(defun list-to-int (l)
  (labels ((n (l e)
	     (if (null l) 0
		 (+ (* (car l) (expt 10 e)) (n (cdr l) (+ 1 e))))))
    (n l 0)))

(defun read-money (s)
  (iterate (initially (setq c #\0))
           (for c next (read-char s))
           (with prec = -1)
           (with e = 0)
           (cond 
             ((digit-char-p c)
	      (when (not (read-from-string (string c))) (leave))
	      (collect (read-from-string (string c)) into num at beginning)
              (incf e)
              (when (<= 0 prec) (incf prec)))
             ((eq c #\.) (incf prec))
             (t (unread-char c s) (terminate)))
           (finally
	    (return `(make-money :amount ,(/ (list-to-int num) (if (< 0 prec) (expt 10 prec) 1))
                                 :prec ,(if (< 0 prec) prec 0))))))

(set-dispatch-macro-character #\# #\$
 #'(lambda (s disp arg)
   (declare (ignore disp arg))
   (read-money s)))
